﻿using PLCCommunication;
using System.Net;
using System.Threading.Tasks;

namespace PLC
{
    /// <summary>
    /// PLC基类
    /// </summary>
    public abstract class PlcReadWriteBase : IPLC
    {
        /// <summary>
        ///  构造一个新的PLC对象
        /// </summary>
        /// <param name="pid"></param>
        /// <param name="pname">plc名</param>
        /// <param name="iep">PLC的IP和端口</param>
        /// <param name="timeout">PLC的通讯超时时间</param>
        public PlcReadWriteBase(int pid, string pname, IPEndPoint iep, int timeout = 10)
        {
            this.zPlcID = pid;
            this.zName = pname;
            this.IP = iep.Address.ToString();
            this.Port = iep.Port;
            this.Timeout = timeout;
        }
        /// <summary>
        /// 
        /// </summary>
        protected string zName;// 允许继承类以后可以更改名称
        /// <summary>
        /// 
        /// </summary>
        protected int zPlcID;
        /// <summary>
        /// 
        /// </summary>
        public string Name { get { return zName; } }
        /// <summary>
        /// 
        /// </summary>
        public int PlcID { get { return zPlcID; } }
        /// <summary>
        /// Ip地址
        /// </summary>
        public string IP { get; private set; }
        /// <summary>
        /// 端口号
        /// </summary>
        public int Port { get; private set; }
        /// <summary>
        /// 是否链接成功
        /// </summary>
        public bool IsConnected { get; set; }
        /// <summary>
        /// PLC 的通讯超时时间
        /// </summary>
        public int Timeout { get; private set; }
        /// <summary>
        /// 链接PLC
        /// </summary>
        public abstract bool Connect(ref string msg);
        /// <summary>
        /// 断开PLC
        /// </summary>
        public abstract bool Disconnect();
        /// <summary>
        /// 读取Plc内部boo变量
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public abstract bool ReadBool(string address);
        /// <summary>
        /// 读取单个Int16整数
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public abstract short ReadInt16(string address);
        /// <summary>
        /// 异步读取单个Int16整数
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public abstract Task<JYResult<short>> ReadInt16Async(string address);
        /// <summary>
        /// 读取Int16数组
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public abstract short[] ReadArrInt16(string address, ushort length);
        /// <summary>
        /// 异步读取Int16数组
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public abstract Task<JYResult<short[]>> ReadArrInt16Async(string address, ushort length);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public abstract int ReadInt32(string address);
        /// <summary>
        ///  异步读取整数32位
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public abstract Task<JYResult<int>> ReadInt32Async(string address);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public abstract float ReadFloat(string address);
        /// <summary>
        /// 读取float数组
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public abstract float[] ReadArrFloat(string address, ushort length);
        /// <summary>
        /// 异步读取float数组
        /// </summary>
        /// <param name="address"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public abstract Task<JYResult<float[]>> ReadArrFloatAsync(string address, ushort length);

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="address"></param>
        /// <param name="type"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public abstract T ReadValue<T>(string address, DataType type, ushort length = 0);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        public abstract bool WriteBool(string address, bool value);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public abstract bool WriteInt16(string address, short value);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public abstract bool WriteInt32(string address, int value);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public abstract bool WriteFloat(string address, float value);
        /// <summary>
        /// 泛型写入数据
        /// </summary>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public abstract JYResult WriteValue(string address, object value, PLC.DataType type = PLC.DataType.Short);


    }
}
